package org.singledog.permission.filter;

import org.apache.commons.lang3.StringUtils;
import org.singledog.permission.core.PermissionApplicationContext;
import org.singledog.permission.core.PermissionSource;
import org.singledog.permission.exception.PermissionExceptionHolder;
import org.singledog.permission.utils.IpUtils;
import org.singledog.permission.utils.JwtUtils;
import org.singledog.permission.utils.TokenBean;

import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Permission核心filter，如果觉得此filter不满足业务需求，可以进行更换
 * 此filter继承自{@link PermissionFilter}
 * 对应的自动装配类{@link org.singledog.permission.config.PermissionFilterAutoConfiguration}
 *
 * @author liuzheming
 * @since 2021.9.14
 */
public class PermissionCoreFilter extends PermissionFilter {

    private Long expire;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        super.init(filterConfig);
        this.expire = Long.valueOf(filterConfig.getInitParameter("expire"));
    }

    /**
     * 前置执行filter，{@link PermissionFilter}
     */
    @Override
    protected List<PermissionSource> preHandFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException {
        long currentTimeMillis = System.currentTimeMillis();
        String authorization = request.getHeader("Authorization");
        Map<String, Object> user = JwtUtils.verifyToken(authorization);
        if (user == null) {
            throw PermissionExceptionHolder.NO_LOGIN.getPermissionException();
        }
        String userId = (String) user.get("userId");
        String permission = (String) user.get("permission");
        TokenBean tokenBean = PermissionApplicationContext.userMap.get(userId);
        String ipAddr = IpUtils.getIpAddr(request);
        if (!(tokenBean != null &&
                tokenBean.getIpToken().get(ipAddr) != null &&
                    tokenBean.getIpToken().get(ipAddr).get(authorization) != null &&
                        (currentTimeMillis - tokenBean.getIpToken().get(ipAddr).get(authorization)) < expire)) {
            throw PermissionExceptionHolder.TOKEN_TIME_OUT.getPermissionException();
        }
        List<PermissionSource> havePermissions = new ArrayList<>();
        if (StringUtils.isNotBlank(permission)) {
            havePermissions = Arrays.stream(permission.split(",")).map(a -> new PermissionSource(a)).collect(Collectors.toList());
        }
        return havePermissions;
    }

    /**
     * 后置执行filter，{@link PermissionFilter}
     */
    @Override
    protected void afterHandFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain, boolean isSuccess) throws IOException, ServletException {
        if (isSuccess) {
            chain.doFilter(request, response);
        } else {
            throw PermissionExceptionHolder.NO_AUTHORIZATION.getPermissionException();
        }
    }
}
